<template>
  <div class="chart">
    <!-- Tab 标签页组件 收入支出分类 -->
    <van-tabs
      v-model="active"
      color="#1989fa"
      line-width=30%
      @change="handleChange"
    >
      <van-tab title="支出" />
      <van-tab title="收入" />
    </van-tabs>
    <!-- 时间 -->
    <span class="date" @click="show=!show" v-if="data.length">
      {{ year+'年'+month+'月' }}<van-icon name="play" class="dir" />
    </span>
    <!-- 图表 -->
    <div id="app" v-if="options.labels.length">
      <schart class="wrapper" canvasId="canvas" :options="options" />
    </div>
    <van-empty
      v-else
      class="custom-image"
      image="https://img01.yzcdn.cn/vant/custom-empty-image.png"
      description="暂无数据"
    />
    <!-- Popup 弹出层组件 弹出年月选择 -->
    <van-popup
      v-model="show"
      position="bottom"
      :style="{height:'38%'}"
    >
      <!-- DatetimePicker 时间选择组件 选择年月 -->
      <van-datetime-picker
        v-model="currentDate"
        type="year-month"
        title="选择年月"
        :min-date="minDate"
        :max-date="maxDate"
        :formatter="formatter"
        @cancel="show=!show"
        @confirm="handleChangeDate"
      />
    </van-popup>
    <!-- Cell 单元格组件 显示种类数据 -->
    <van-cell
      v-for="(category, index) in this.options.labels"
      :key="index"
    >
      <!-- 使用 title 插槽来自定义标题 -->
      <template #title>
        <span class="color" :style=handleGetBackgorund(index)></span>
        <span class="custom-title">{{ category }}</span>
        <span class="item">{{ itemSum[index].toFixed(2) }}</span>
        <span class="all">{{ ((itemSum[index] / allSum)*100).toFixed(2) + '%' }}</span>
      </template>
    </van-cell>
    <!--  -->
  </div>
</template>

<script>
import Schart from 'vue-schart'
export default {
  name: 'chart',
  created () {
    // 未登录时不渲染数据
    if (!this.$store.state.username) return
    this.year = (new Date()).getFullYear()
    this.month = (new Date()).getMonth() + 1
    this.handleGetDate()
  },
  data () {
    /**
    * options 饼状图配置
    * active 选中的标签
    * payData 支出数据
    * incomeData 收入数据
     */
    return {
      options: {
        type: 'pie',
        bgColor: '#f7f8fa',
        title: {
          text: '支出饼状图',
        },
        showValue: false,
        colorList: ['#4a90e2', '#f5a623', '#ff5858', '#5e64ff', '#2ac766', '#743ee2', '#b554ff', '#199475'],
        legend: {
          position: 'left',
          font: '26px Arial',
          display: false,
        },
        labels: [],
        datasets: [{
          data: [0, 0, 0, 0, 0, 0, 0, 0],
        }],
        radius: 200,
      },
      active: 0,
      payData: [],
      incomeData: [],
      minDate: new Date(2020, 0, 1),
      maxDate: new Date(2025, 10, 1),
      currentDate: new Date(),
      show: false,
      month: '',
      year: '',
      data: {},
    }
  },
  computed: {
    itemSum () {
      return this.options.datasets[0].data
    },
    allSum () {
      return this.options.datasets[0].data.reduce((sum, value) => sum + value, 0)
    },
  },
  components: {
    Schart,
  },
  methods: {
    // 当前选中的标签改变时触发
    handleChange (name) {
      // 初始化数据
      this.options.labels = []
      this.options.datasets[0].data = [0, 0, 0, 0, 0, 0, 0, 0]
      if (name === 0) {
        this.handleToggle(this.payData)
        this.options.title.text = '支出饼状图'
      } else {
        this.handleToggle(this.incomeData)
        this.options.title.text = '收入饼状图'
      }
    },
    handleGetDate () {
      const month = this.month < 10 ? '0' + this.month : this.month
      const min = this.year + month + '00'
      const max = this.year + month - 0 + 1 + '00'
      // 获取当前用户的数据
      this.data = this.$store.state.userInfo.filter(user => user.username === this.$store.state.username)[0].data
      // 获取 store 中用户数据，金额大于 0 的是收入，小于 0 的是支出
      this.payData = this.data.filter(item => item.money < 0 && item.dateString > min && item.dateString < max)
      this.incomeData = this.data.filter(item => item.money > 0 && item.dateString > min && item.dateString < max)
      // 调用渲染函数
      this.active === 0 && this.handleToggle(this.payData)
      this.active === 1 && this.handleToggle(this.incomeData)
    },
    // 渲染函数，当前选中的标签改变时触发，可用于渲染支出和收入的图表
    handleToggle (typeData) {
      // 初始化数据
      this.options.labels = []
      this.options.datasets[0].data = [0, 0, 0, 0, 0, 0, 0, 0]
      // 找出用户存储的所有数据分类
      typeData.forEach(item => {
        !this.options.labels.includes(item.category) && this.options.labels.push(item.category)
      })
      // 将所有分类对应的金额总和对应计算出来
      this.options.labels.forEach((label, index) => {
        typeData.forEach(item => {
          label === item.category && (this.options.datasets[0].data[index] += Math.abs(item.money))
        })
      })
    },
    handleGetBackgorund (index) {
      return {
        background: this.options.colorList[index],
      }
    },
    formatter (type, val) {
      if (type === 'month') {
        return `${val}月`
      } else if (type === 'year') {
        return `${val}年`
      }
      return val
    },
    handleChangeDate (value) {
      this.year = value.getFullYear()
      this.month = value.getMonth() + 1
      this.handleGetDate()
      this.show = !this.show
    },
  },
}
</script>

<style lang="less" scoped>
.chart{
  position: relative;
}
.wrapper{
    height: 10rem;
    width: 100%;
}
.color{
  display: inline-block;
  width: 10px;
  height: 10px;
  margin-right: 10px;
}
.item{
  margin-left: 130px;
}
.all{
  float: right;
}
.van-cell{
  padding-left: 30px;
  padding-right: 30px;
}
.date{
  position: absolute;
  left: 50%;
  margin-left: -44px;
  top: 80px;
  font-size: 16px;
  font-weight: bold;
  color: #555;
}
.dir{
  transform: rotate(90deg);
}
/deep/.van-empty {
  margin: 40px;
}
</style>
